=begin
1.
=end

# 定义方法
def tell_the_truth
  true
end

puts tell_the_truth

# 数组
annimals = ['鸡', '鸭', '鹅']
#puts annimals
puts annimals[0]
puts annimals[1]
puts annimals[2]
puts annimals[-1]
puts annimals[-2]
puts annimals[-3]

puts [].class

# 散列表
numbers = {1 => 'one', 2 => 'two'}
puts numbers
puts numbers[1]
puts numbers[2]

test = {:array => [1, 2, 3], :string => '我是张三'}
puts test
puts test[:string]

# :symbol 符号，相同的符号标识同一个对象，相同字符串不表示同一个字符串
puts '123'.object_id
puts '123'.object_id # 相同字符串的object_id不同
puts :'123'.object_id
puts :'123'.object_id # 相同符号的object_id相同

# 代码块和yield
# 代码块只占一行时用{}
# 代码块占多行时用do/end
3.times {puts 'I am zhangsan'}

annimals.each { |x| puts x + '叫' }

# 打开现有的Integer类，添加my_times方法，使用yield调用代码块
class Integer
  def my_times
    i = self
    while i > 0
      i = i - 1
      yield
    end
  end
end
3.my_times {puts 'I am lisi'}

# 代码块可以作为一等参数，将代码块（函数）作为参数传递给函数
def call_block(&block) # &表示将代码块作为闭包传递给函数
  block.call
end

def pass_block(&block)
  call_block(&block)
end

# 将可执行代码派发给其他方法
pass_block {puts '你好宝宝蛋'}

# 延迟执行

# 类
class Tree # 类名大写，驼峰
  # 定义实例变量和访问变量的同盟方法
  attr_accessor :children, :node_name
  # 初始化方法
  def initialize(name, children = [])
    # 实例变量前@，下划线命名
    @children = children
    @node_name = name
  end

  def visit(&block)
    block.call self
  end

  def visit_all(&block)
    visit &block
    children.each { |x| x.visit_all &block }
  end
end

dandan_tree = Tree.new("小宝", [Tree.new("蛋蛋"), Tree.new("小蛋")])
puts "visiting a node"
dandan_tree.visit { |node| puts node.node_name}
puts
puts "visiting all nodes"
dandan_tree.visit_all { |node| puts node.node_name}

# 通过模块混入实现java接口的效果
module ToFile
  def fileName
    "object_#{self.object_id}.txt"
  end

  def to_f
    File.open(fileName, 'w') { |f| f.write(to_s)}
  end
end

class Person
  include ToFile
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def to_f
    name
  end
end

puts Person.new('张三').to_f

# 枚举（enumerable） 比较（comparable）
puts 'begin' <=> 'end'
puts 1 <=> 1

a = [5, 4, 3, 2, 1]
puts a.sort
puts
puts a.any? { |x| x > 6}
puts
puts a.any? { |x| x > 4}
puts
puts a.all? { |x| x > 4}
puts
puts a.collect { |x| x * 2}
puts
puts a.map { |x| x + 1 }
puts
puts a.select { |x| x % 2 == 0}
puts
puts a.select { |x| x % 2 == 1} # select 找出所有服务条件的 相当于find_all
puts
puts a.find { |x| x % 2 == 0} # find 找到一个符合条件的
puts
puts a.max
puts
puts a.min
puts
puts a.inject { |sum, x| sum + x}
puts
puts a.inject { |product, x| product * x}
